﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Tools.Custom
{
    public class CustomButton : System.Windows.Forms.Button
    {
        #region 属性

        private int _roundAngle = 5;
        private Color _borderColor = System.Drawing.ColorTranslator.FromHtml("#1E9FFF");
        private Color _fillColor = System.Drawing.ColorTranslator.FromHtml("#1E9FFF");
        private Color _fillColor_Enter = System.Drawing.ColorTranslator.FromHtml("#4BB2FF");

        /// <summary>
        /// 控件边框颜色
        /// </summary>
        [Category("自定义"), DefaultValue(typeof(Color), "#E4E4E4"), Description("控件边框颜色")]
        public Color BorderColor
        {
            get => _borderColor; set => _borderColor = value;
        }

        /// <summary>
        /// 圆角大小
        /// </summary>
        [Category("自定义"), DefaultValue(5), Description("圆角大小")]
        public int RoundAngle
        {
            get => _roundAngle; set => _roundAngle = value;
        }

        /// <summary>
        /// 默认填充背景色
        /// </summary>
        [Category("自定义"), DefaultValue(typeof(Color), "#56D668"), Description("默认填充背景色")]
        public Color FillColor { get => _fillColor; set => _fillColor = value; }

        /// <summary>
        /// 鼠标经过填充背景色
        /// </summary>
        [Category("自定义"), DefaultValue(typeof(Color), "#32C848"), Description("鼠标经过填充背景色")]
        public Color FillColor_Enter { get => _fillColor_Enter; set => _fillColor_Enter = value; }

        /// <summary>
        /// 填充背景色
        /// </summary>
        private Color fillBackColor { get; set; }

        /// <summary>
        /// 是否第一次
        /// </summary>
        private bool isFirst { get; set; }

        #endregion

        #region 绘制填充色

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (!this.isFirst)
            {
                this.FlatStyle = FlatStyle.Flat;
                this.FlatAppearance.BorderSize = 0;
                this.FlatAppearance.MouseDownBackColor = Color.Transparent;
                this.FlatAppearance.MouseOverBackColor = Color.Transparent;
                this.fillBackColor = this.FillColor;
                this.Cursor = Cursors.Hand;
                this.isFirst = true;
            }

            if (this.RoundAngle > 0)
            {
                this.Margin = new Padding(1);
                int width = base.Width - base.Margin.Left - base.Margin.Right;
                int height = base.Height - base.Margin.Top - base.Margin.Bottom;
                Rectangle rec = new Rectangle(base.Margin.Left, base.Margin.Top, width, height);
                GraphicsPath round = CreateRound(rec, this.RoundAngle);
                e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
                e.Graphics.FillPath((Brush)(new SolidBrush(this.fillBackColor)), round);

                //字体处理
                var sf = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };
                var brush = new SolidBrush(this.ForeColor);
                e.Graphics.DrawString(this.Text, this.Font, brush, rec, sf);
            }
        }

        protected GraphicsPath CreateRound(Rectangle rect, int radius)
        {
            GraphicsPath roundRect = new GraphicsPath();
            //顶端 
            roundRect.AddLine(rect.Left + radius - 1, rect.Top - 1, rect.Right - radius, rect.Top - 1);
            //右上角 
            roundRect.AddArc(rect.Right - radius, rect.Top - 1, radius, radius, 270, 90);
            //右边 
            roundRect.AddLine(rect.Right, rect.Top + radius, rect.Right, rect.Bottom - radius);
            //右下角

            roundRect.AddArc(rect.Right - radius, rect.Bottom - radius, radius, radius, 0, 90);
            //底边 
            roundRect.AddLine(rect.Right - radius, rect.Bottom, rect.Left + radius, rect.Bottom);
            //左下角 
            roundRect.AddArc(rect.Left - 1, rect.Bottom - radius, radius, radius, 90, 90);
            //左边 
            roundRect.AddLine(rect.Left - 1, rect.Top + radius, rect.Left - 1, rect.Bottom - radius);
            //左上角 
            roundRect.AddArc(rect.Left - 1, rect.Top - 1, radius, radius, 180, 90);
            return roundRect;
        }
        #endregion

        #region 重绘圆角边框

        protected override void WndProc(ref Message m)
        {
            try
            {
                base.WndProc(ref m);
                if (m.Msg == 0xF)
                {
                    if (this.RoundAngle > 0)
                    {
                        using (Graphics g = Graphics.FromHwnd(this.Handle))
                        {
                            Rectangle r = new Rectangle();
                            r.Width = this.Width;
                            r.Height = this.Height;
                            DrawBorder(g, r, this.RoundAngle);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void DrawBorder(Graphics g, Rectangle rect, int radius)
        {
            rect.Width -= 1;
            rect.Height -= 1;
            using (GraphicsPath path = CreatePath(rect, radius, false))
            {
                using (Pen pen = new Pen(this.BorderColor))
                {
                    g.DrawPath(pen, path);
                }
            }
        }

        /// <summary>
        /// 建立带有圆角样式的路径。
        /// </summary>
        /// <param name="rect">用来建立路径的矩形。</param>
        /// <param name="_radius">圆角的大小。</param>
        /// <param name="style">圆角的样式。</param>
        /// <param name="correction">是否把矩形长宽减 1,以便画出边框。</param>
        /// <returns>建立的路径。</returns>
        GraphicsPath CreatePath(Rectangle rect, int radius, bool correction)
        {
            GraphicsPath path = new GraphicsPath();
            int radiusCorrection = correction ? 1 : 0;

            path.AddArc(rect.X, rect.Y, radius, radius, 180, 90);
            path.AddArc(rect.Right - radius - radiusCorrection, rect.Y, radius, radius, 270, 90);
            path.AddArc(rect.Right - radius - radiusCorrection, rect.Bottom - radius - radiusCorrection, radius, radius, 0, 90);
            path.AddArc(rect.X, rect.Bottom - radius - radiusCorrection, radius, radius, 90, 90);

            path.CloseFigure(); //这句很关键，缺少会没有左边线。
            return path;
        }
        #endregion

        #region 鼠标经过 离开

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            this.fillBackColor = this.FillColor_Enter;
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.fillBackColor = this.FillColor;
        }

        protected override void OnLayout(LayoutEventArgs levent)
        {
            base.OnLayout(levent);
            this.fillBackColor = this.FillColor;
        }
        #endregion

        /// <summary>
        /// 更新
        /// </summary>
        public new void Update()
        {
            this.fillBackColor = this.FillColor;
        }
    }
}